﻿using JNPF.Basics.Models;
using JNPF.Basics.Models.Extend.Dtos.Order;
using JNPF.Utils;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Transactions;

namespace JNPF.Basics.Logic
{
    /// <summary>
    /// 订单管理
    /// 版 本：V3.0.0
    /// 版 权：引迈信息技术有限公司（https://www.jnpfsoft.com）
    /// 作 者：JNPF开发平台组
    /// 日 期：2017-12-11 
    /// </summary>
    public class OrderBll
    {
        private OrderIService service = new OrderService();
        private FlowTaskBll flowTaskBll = new FlowTaskBll();
        private FlowTaskNodeBll flowTaskNodeBll = new FlowTaskNodeBll();
        private FlowEngineBll flowEngineBll = new FlowEngineBll();
        private FlowTaskService flowTaskService = new FlowTaskService();
        /// <summary>
        /// 列表
        /// </summary>
        /// <param name="input">请求参数</param>
        /// <returns></returns>
        public async Task<PageResult<OrderEntity>> GetList(PageInput input)
        {
            try
            {
                var list= await service.GetList(input);
                var flowTaskList =await flowTaskService.GetList();
                list.list.ForEach(m => m.CurrentState = flowTaskList.Find(x => x.Id == m.Id).IsEmpty() ? null : flowTaskList.Find(x => x.Id == m.Id).Status);
                return list;
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 子列表（订单明细）
        /// </summary>
        /// <param name="id">主表Id</param>
        /// <returns></returns>
        public async Task<List<OrderEntryEntity>> GetOrderEntryList(string id)
        {
            try
            {
                return await service.GetOrderEntryList(id);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 子列表（订单收款）
        /// </summary>
        /// <param name="id">主表Id</param>
        /// <returns></returns>
        public async Task<List<OrderReceivableEntity>> GetOrderReceivableList(string id)
        {
            try
            {
                return await service.GetOrderReceivableList(id);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 信息（前单、后单）
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="method">方法:prev、next</param>
        /// <returns></returns>
        public async Task<OrderEntity> GetPrevOrNextInfo(string id, string method)
        {
            try
            {
                return await service.GetPrevOrNextInfo(id, method);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 信息
        /// </summary>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public async Task<OrderEntity> GetInfo(string id)
        {
            try
            {
                return await service.GetInfo(id);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="entity">订单信息</param>
        public async Task Delete(OrderEntity entity)
        {
            try
            {
                await service.Delete(entity);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="entity">订单信息</param>
        /// <param name="orderEntryList">订单明细</param>
        /// <param name="orderReceivableList">订单收款</param>
        public async Task Create(OrderCrInput input)
        {
            try
            {
                var orderEntity = input.MapTo<OrderEntity>();
                var orderEntryList = input.goodsList.MapToList<OrderEntryEntity>();
                var orderReceivableList = input.collectionPlanList.MapToList<OrderReceivableEntity>();
                orderEntity.Id = CommonHelper.Guid;
                orderEntity.CreatorTime = DateTime.Now;
                orderEntity.CreatorUserId = UserProvider.Instance.Get().UserId;
                foreach (var itemEntity in orderEntryList)
                {
                    itemEntity.Id = CommonHelper.Guid;
                    itemEntity.OrderId = orderEntity.Id;
                    itemEntity.SortCode = orderEntryList.IndexOf(itemEntity);
                }
                foreach (var itemEntity in orderReceivableList)
                {
                    itemEntity.Id = CommonHelper.Guid;
                    itemEntity.OrderId = orderEntity.Id;
                    itemEntity.SortCode = orderReceivableList.IndexOf(itemEntity);
                }
                BillRuleBll.UseBillNumber("OrderNumber");
                await service.Create(orderEntity, orderEntryList, orderReceivableList);
                if (input.status == 0)
                {
                    var flowModuleMark = FlowModuleEnum.CRM_Order;
                    var flowEngineEntity = await flowEngineBll.GetInfoByEnCode(flowModuleMark);
                    await FlowSubmit(orderEntity.Id, flowEngineEntity, input.freeApproverUserId);
                }
                FileManage.CreateFile(JsonHelper.ToList<FileModel>(orderEntity.FileJson));

            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="entity">订单信息</param>
        /// <param name="orderEntryList">订单明细</param>
        /// <param name="orderReceivableList">订单收款</param>
        public async Task Update(string id, OrderUpInput input)
        {
            try
            {
                var entity = input.MapTo<OrderEntity>();
                var orderEntryList = input.goodsList.MapToList<OrderEntryEntity>();
                var orderReceivableList = input.collectionPlanList.MapToList<OrderReceivableEntity>();
                entity.Id = id;
                entity.LastModifyTime = DateTime.Now;
                entity.LastModifyUserId = UserProvider.Instance.Get().UserId;
                foreach (var orderEntryEntity in orderEntryList)
                {
                    orderEntryEntity.Id = CommonHelper.Guid;
                    orderEntryEntity.OrderId = entity.Id;
                    orderEntryEntity.SortCode = orderEntryList.IndexOf(orderEntryEntity);
                }
                foreach (var orderReceivableEntity in orderReceivableList)
                {
                    orderReceivableEntity.Id = CommonHelper.Guid;
                    orderReceivableEntity.OrderId = entity.Id;
                    orderReceivableEntity.SortCode = orderReceivableList.IndexOf(orderReceivableEntity);
                }
                if ("0".Equals(input.status))
                {
                    var flowModuleMark = FlowModuleEnum.CRM_Order;
                    var flowEngineEntity = await flowEngineBll.GetInfoByEnCode(flowModuleMark);
                    await FlowSubmit(id, flowEngineEntity, input.freeApproverUserId);
                }
                FileManage.CreateFile(JsonHelper.ToList<FileModel>(entity.FileJson));
                await service.Update(entity, orderEntryList, orderReceivableList);
            }
            catch (Exception ex)
            {
                throw ExceptionEx.Throw(ex);
            }
        }
        /// <summary>
        /// 提交审核
        /// </summary>
        /// <param name="id">主键值</param>
        /// <param name="flowEngineEntity">流程信息</param>
        /// <param name="freeApproverUserId">授权审批人</param>
        /// <returns></returns>
        public async Task FlowSubmit(string id, FlowEngineEntity flowEngineEntity, string freeApproverUserId)
        {
            var userInfo = UserProvider.Instance.Get();
            var orderEntity = await this.GetInfo(id);
            using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                #region 业务信息
                orderEntity.CurrentState = FlowTaskStatusEnum.Handle;
                orderEntity.LastModifyTime = DateTime.Now;
                orderEntity.LastModifyUserId = userInfo.UserId;
                await service.Update(orderEntity);
                #endregion

                #region 流程信息
                await flowTaskBll.Submit(id, flowEngineEntity.Id, userInfo.UserName + "的订单示例", 1, orderEntity.OrderCode, orderEntity.MapTo<OrderInfo>(), freeApproverUserId);
                #endregion

                scope.Complete();
            }
        }
        /// <summary>
        /// 撤回审核
        /// </summary>
        /// <param name="flowTaskEntity">流程任务</param>
        /// <param name="flowHandleModel">流程经办</param>
        public async Task FlowRevoke(FlowTaskEntity flowTaskEntity, string flowHandleModel)
        {
            var orderEntity = await this.GetInfo(flowTaskEntity.ProcessId);
            using (TransactionScope scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                #region 业务信息
                orderEntity.CurrentState = FlowTaskStatusEnum.Revoke;
                orderEntity.LastModifyTime = DateTime.Now;
                await service.Update(orderEntity);
                #endregion

                #region 流程信息
                var flowTaskNodeEntityList = await flowTaskNodeBll.GetList(flowTaskEntity.Id);
                var flowTaskNodeEntity = flowTaskNodeEntityList.Find(m => m.SortCode == 2);
                if (flowTaskNodeEntity.Completion > 0)
                {
                    throw new Exception("当前流程被处理，无法撤回流程");
                }
                else
                {
                    await flowTaskBll.Revoke(flowTaskEntity, flowHandleModel);
                }
                #endregion

                scope.Complete();
            }
        }
        /// <summary>
        /// 流程事件
        /// </summary>
        /// <param name="flowHandleEvent">经办事件</param>
        /// <param name="flowEngineEntity">流程任务</param>
        public async Task FlowHandleEvent(FlowHandleEventEnum flowHandleEvent, FlowTaskEntity flowTaskEntity)
        {
            var orderEntity = await this.GetInfo(flowTaskEntity.ProcessId);
            if (orderEntity != null)
            {
                orderEntity.CurrentState = flowTaskEntity.Status;
                await service.Update(orderEntity);
            }
        }
    }
}
